home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 March / CHIP Mart 1997.iso / prg / driveroc / CPUTEST.ASM < prev    next >
Encoding:
Assembly Source File  |  1995-11-22  |  30.6 KB  |  800 lines

  1. ;
  2. ; CPUTEST.ASM - Copyright (C) 1993 - Tony Doimeadios - All Rights Reserved
  3. ;
  4. ;         Made-----------: 09/30/93
  5. ;         Last Modified--: 10/01/93
  6. ;         Last Modified--: 10/11/93 Added file i/o to record info & comments
  7. ;         Last Modified--: 10/15/93 Added 80386-specific code to test routines
  8.  
  9.     
  10.     DOSSEG
  11.     .MODEL LARGE
  12.     .STACK
  13.     .DATA?
  14. Buffer1 db  25000 DUP (?)       ;buffer to copy from
  15. Buffer2 db  25000 DUP (?)       ;buffer to copy to
  16.  
  17.     .DATA
  18. StartLow    dw  0               ;variable to store the low word of start ticks
  19. FinishLow   dw  0               ;variable to store the low word of stop ticks
  20. Counter     dw  0               ;variable to store loop counter
  21. Dummy       dw  0               ;dummy word variable for variable-2-reg proc
  22. BigDummy    dd  0               ;dummy word variable for variable-2-ex reg
  23. CRLF        db  13,10,'$'
  24. UserInput   db  71 DUP (' ')
  25.             db  13,10
  26. Prompt      db  'Please enter a brief description of system',13,10
  27.             db  '(ex. 80386DX-33MHz, 64K Cache, 4 Meg Ram, CoProcessor, DOS 5.0)',13,10
  28.             db  '         1         2         3         4         5         6         7   ',13,10
  29.             db  '1234567890123456789012345678901234567890123456789012345678901234567890123',13,10,'$'
  30. FileName    db  'CPUTEST.TXT',0
  31. Handle      dw  0
  32. BadCreate   db  13,10,7,7,'An error occured while trying to create the report file...',13,10,'$'
  33.  
  34.             ;         1         2         3         4         5         6         7         8
  35.             ;12345678901234567890123456789012345678901234567890123456789012345678901234567890    len=74 (includes $)
  36. Output1  db 'It took       timer ticks to move 8 million bytes...                   ',13,10,'$'
  37. Output2  db 'It took       timer ticks to do 8 million register-to-register moves...',13,10,'$'
  38. Output3  db 'It took       timer ticks to do 8 million variable-to-register moves...',13,10,'$'
  39. Output4  db 'It took       timer ticks to move 100 million bytes...                 ',13,10,'$'
  40. Output5  db 'It took  N/A  timer ticks to do 8 million ext reg-to-ext reg moves...  ',13,10,'$'
  41. Output6  db 'It took  N/A  timer ticks to do 8 million variable-to-ext reg moves... ',13,10,'$'
  42. Msg386   db 13,10
  43.          db '                   80386 Specific Instructions                       ',13,10,'$'
  44. Delimit  db 71 DUP ('*')    ;this is a string of *'s, to mark off visually
  45.          db 13,10
  46.     
  47.     .CODE
  48.     .386
  49.     mov ax,@Data
  50.     mov ds,ax                   ;set DS to point to the data segment
  51.  
  52.     jmp Start                   ;jmp over procs
  53.  
  54.  
  55. ;   PROCS (put at beginning)
  56. ;---------------------------------------------------------------------
  57. ;---------------------------------------------------------------------
  58. ;---------------------------------------------------------------------
  59. ; Subroutine to convert a binary number to a text string.
  60. ;
  61. ; Input:
  62. ;       ax = number to convert
  63. ;       DS:BX = pointer to end of string to store text in
  64. ;       CX = number of digits to convert
  65. ;
  66. ; Output: None
  67. ;
  68. ; Registers destroyed: ax, BX, CX, DX, SI
  69. ;
  70. Num2Str   PROC NEAR
  71.         mov     si,10           ;used to divide by 10
  72. ConvertLoop:
  73.         sub     dx,dx           ;convert ax to doubleword in DX:ax
  74.         div     si              ;divide number by 10. Remainder is in
  75.                                 ; DX--this is a one-digit decimal
  76.                                 ; number. Number/10 is in ax
  77.         add     dl,'0'          ;convert remainder to a text character
  78.         mov     [bx],dl         ;put this digit in the string
  79.         dec     bx              ;point to the location for the
  80.                                 ; next most-significant digit
  81.         loop    ConvertLoop     ;do the next digit, if any
  82.         ret
  83. Num2Str   ENDP
  84. ;---------------------------------------------------------------------
  85.  
  86.  
  87. ;---------------------------------------------------------------------
  88. ; Subroutine to print a string on the display.
  89. ;
  90. ; Input:
  91. ;       DS:BX = pointer to string to print
  92. ;
  93. ; Output: None
  94. ;
  95. ; Registers destroyed: None
  96. ;
  97. PrintString     PROC NEAR
  98.         push    ax
  99.         push    dx              ;preserve registers in this sub
  100.         mov     ah,9            ;DOS print string function #
  101.         mov     dx,bx           ;point DS:DX to the string to print
  102.         int     21h             ;invoke DOS to print the string
  103.         pop     dx              ;restore registers we changed
  104.         pop     ax              ;restore registers we changed
  105.         ret                     ;bail out
  106. PrintString     ENDP
  107. ;---------------------------------------------------------------------
  108.  
  109.  
  110.  
  111.  
  112. ;---------------------------------------------------------------------
  113. MemoryMove PROC NEAR
  114.     
  115.     mov ax,SEG Buffer1          ;get segment of ROM BIOS
  116.     mov es,ax                   ;put it in ds
  117.     mov di,OFFSET Buffer1       ;get offset of buffer
  118.  
  119.     mov ax,SEG Buffer2          ;get segment of Buffer2
  120.     mov ds,ax                   ;put it in es
  121.     mov si,0                    ;get offset of buffer
  122.  
  123.     mov cx,25000                ;gonna move 25000 bytes
  124.     rep movsb                   ;do it until cx=0
  125.  
  126.     ret                         ;done - bail out
  127.  
  128. MemoryMove ENDP
  129. ;---------------------------------------------------------------------
  130.  
  131.  
  132.  
  133.  
  134. ;---------------------------------------------------------------------
  135. RegToReg PROC NEAR
  136.     mov cx,25000                ;setup for 25000 times
  137.     
  138. MoveLoop:
  139.     mov es,ax                   ;do register to register move
  140.     loop MoveLoop               ;do it 25000 times
  141.  
  142.     ret                         ;done - bail out
  143.  
  144. RegToReg ENDP
  145. ;---------------------------------------------------------------------
  146.  
  147.  
  148.  
  149.  
  150. ;---------------------------------------------------------------------
  151. MemToReg PROC NEAR
  152.     mov cx,25000                ;setup for 25000 times
  153.     
  154. MemLoop:
  155.     mov dx,Dummy                ;do variable to register move
  156.     loop MemLoop                ;do it 25000 times
  157.  
  158.     ret                         ;done - bail out
  159.  
  160. MemToReg ENDP
  161. ;---------------------------------------------------------------------
  162.  
  163.  
  164.  
  165.  
  166.  
  167. ;                   80386-Specific Procs
  168.  
  169. ;---------------------------------------------------------------------
  170. ERegToEReg PROC NEAR
  171.     mov cx,25000                ;setup for 25000 times
  172.     
  173. MoveELoop:
  174.     mov eax,ebx                 ;do register to register move
  175.     loop MoveELoop              ;do it 25000 times
  176.  
  177.     ret                         ;done - bail out
  178.  
  179. ERegToEReg ENDP
  180. ;---------------------------------------------------------------------
  181.  
  182.  
  183.  
  184.  
  185. ;---------------------------------------------------------------------
  186. MemToEReg PROC NEAR
  187.     mov cx,25000                ;setup for 25000 times
  188.     
  189. MemELoop:
  190.     mov edx,BigDummy            ;do variable to register move
  191.     loop MemELoop               ;do it 25000 times
  192.  
  193.     ret                         ;done - bail out
  194.  
  195. MemToEReg ENDP
  196. ;---------------------------------------------------------------------
  197.  
  198.  
  199.  
  200. ;---------------------------------------------------------------------
  201. MoveEBytes PROC NEAR
  202.     
  203.     ;I don't know the instruction to do a memory move with 32-bit regs
  204.     ret                         ;done - bail out
  205.  
  206. MoveEBytes ENDP
  207. ;---------------------------------------------------------------------
  208.  
  209.  
  210. ;---------------------------------------------------------------------
  211. WhichCPU PROC NEAR
  212.     
  213.     ;Determine whether the CPU in use is an 8086/88, an 80286,
  214.     ;an 80386 or an 80486.  Returns the CPU type in the ax register.
  215.  
  216.     ;The first step is to determine whether the chip is an 8086/8088.
  217.     ;The key difference is based on what the CPU does when it executes
  218.     ;the PUSH instruction.  The 8086/8088 decrements the stack pointer
  219.     ;first, then writes the saved value to the stack, then decrement
  220.     ;the stack pointer.  Thus, when SP is pushed, and the pushed value
  221.     ;is popped off, the value popped off will equal the current stack 
  222.     ;pointer, unless the chip is an 8086 or an 8088.
  223.     
  224.     push sp                     ;push sp
  225.     pop ax                      ;retrieve value
  226.     cmp ax,sp                   ;is it the same value that was pushed?
  227.     je Try286                   ;if same, it is a 80286 or higher
  228.     mov ax,88                   ;nope, set register to reflect 8088
  229.     jmp short ProcDone          ;bail out
  230.  
  231.  
  232.  
  233.     ;the second step is to determine whether the chip is an 80286.
  234.     ;The key difference is the IOPL bits in the flag register; the 80386
  235.     ;and 80486 has them, the 80286 does not.  The 80286 will not allow them
  236.     ;to be set; the 80386 and 80486 will.
  237.  
  238. Try286:
  239.     pushf                       ;push flags
  240.     pop ax                      ;retreive them
  241.     or ax,03000h                ;set IOPL bits
  242.     push ax                     ;stuff back
  243.     popf                        ;pop flags back - this is where the 80286 
  244.                                 ; will put them back the way they were
  245.     pushf                       ;push them back
  246.     pop ax                      ;see if CPU overrode the IOPL bits
  247.     test ax,03000h              ;if the IOPL bits are reset, the CPU did
  248.                                 ; and the chip is an 80286
  249.     jnz Try386                  ;nope, go see if we're an 80386
  250.     mov ax,286                  ;set register to reflect we're an 80286
  251.     jmp short ProcDone          ;bail out
  252.  
  253.     
  254.     
  255.     ;the third step is to determine whether the chip is an 80386.
  256.     ;the key difference is the alignment check bit in the flags
  257.     ;register: the 80486 has one, the 80386 does not.  As with the
  258.     ;80286 and the IOPL bits, the 80386 will not let you set that bit,
  259.     ;but the 80486 will.
  260.  
  261. Try386:
  262.     db 66h                      ;(32 bit)
  263.     pushf                       ;push extended flags register
  264.     pop ax                      ;read low word
  265.     and ax,00fffh               ;clear IOPL bits - level zero
  266.     pop dx                      ;read high word
  267.     or dx,00004h                ;set alignment check bit
  268.     push dx                     ;push flags back
  269.     push ax                     ;push flags back
  270.     db 66h                      ;(32 bit)
  271.     popf                        ;pop flags register - this is where
  272.                                 ; the 80386 will undo your work
  273.     db 66h                      ;(32 bits) 
  274.     pushf                       ;push flags back
  275.     pop ax                      ;read what we did
  276.     pop dx                      ;find out if the CPU reset the
  277.                                 ; alignment check bit
  278.     test dx,4                   ;
  279.     jnz short Try486            ;if it didn't, the chip is an 80486
  280.     mov ax,386                  ;set register to reflect we're an 8386
  281.     jmp short ProcDone          ;bail out
  282.  
  283.  
  284.     ;this routine does NOT take into account the Pentium (80586)
  285.     ;therefore, this routine will report an '486' for both the
  286.     ;80486 and the Pentium chips
  287.     
  288. Try486:
  289.     mov ax,486                  ;must be a 80486
  290.  
  291.  
  292. ProcDone:    
  293.     ret                         ;we're thru - bail out
  294.  
  295. WhichCPU ENDP
  296. ;---------------------------------------------------------------------
  297. ;---------------------------------------------------------------------
  298. ;---------------------------------------------------------------------
  299.  
  300.  
  301.  
  302.  
  303.  
  304. ;                      CODE STARTS HERE
  305.  
  306. ;---------------------------------------------------------------------
  307. Start:    
  308.     ;MEMORY MOVES
  309.     ;
  310.     ;timing loop
  311.     ;
  312.     xor  ax,ax                  ;zero out register
  313.     int 1Ah                     ;how many clock ticks since midnight
  314.     mov StartLow,dx             ;save it (low word)
  315.     
  316.     
  317.     ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  318.     mov Counter,0               ;initialize the loop counter
  319.  
  320. DoIt1:    
  321.     call MemoryMove             ;call the memory mover proc
  322.     inc Counter                 ;inc the counter
  323.     cmp Counter,40*8            ;40 loops = 1 million
  324.     jne DoIt1                   ;if it's not the required # of loops, do more
  325.     ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  326.  
  327.  
  328.     ;timing loop
  329.     ;
  330.     xor  ax,ax                  ;zero out register
  331.     int 1Ah                     ;how many clock ticks since midnight
  332.     mov FinishLow,dx            ;save it (low word)
  333.  
  334.  
  335.     ;get difference from start and stop times
  336.     ;
  337.     xor ax,ax                   ;zero out register
  338.     mov ax,FinishLow            ;put stop times in
  339.     sub ax,StartLow             ;sub start from it - ax now holds difference
  340.  
  341.     mov bx,SEG Output1          ;get segment of Output1 string
  342.     mov ds,bx                   ;put it in ds
  343.     mov bx,OFFSET Output1+12    ;offset is 13 characters into the string
  344.     mov cx,5                    ;convert 5 digits
  345.     call Num2Str
  346.  
  347.     mov bx,SEG Output1          ;get segment of Output1 string
  348.     mov ds,bx                   ;put it in ds
  349.     mov bx,OFFSET Output1       ;get offset of string
  350.     call PrintString            ;print string
  351. ;---------------------------------------------------------------------
  352. ;---------------------------------------------------------------------
  353.  
  354.  
  355.  
  356.  
  357. ;---------------------------------------------------------------------
  358. ;---------------------------------------------------------------------
  359.     ;REGISTER TO REGISTER
  360.     ;
  361.     ;timing loop
  362.     ;
  363.     xor ax,ax                   ;zero out register
  364.     int 1Ah                     ;how many clock ticks since midnight
  365.     mov StartLow,dx             ;save it (low word)
  366.  
  367.     
  368.     ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  369.     mov Counter,0               ;initialize the loop counter
  370.  
  371. DoIt2:    
  372.     call RegToReg               ;call the register to register mover proc
  373.     inc Counter                 ;inc the counter
  374.     cmp Counter,40*8            ;40 loops = 1 million
  375.     jne DoIt2                   ;if it's not the required # of loops, do more
  376.     ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  377.  
  378.  
  379.     ;timing loop
  380.     ;
  381.     xor ax,ax                   ;zero out register
  382.     int 1Ah                     ;how many clock ticks since midnight
  383.     mov FinishLow,dx            ;save it (low word)
  384.  
  385.  
  386.     ;get difference from start and stop times
  387.     xor ax,ax                   ;zero out register
  388.     mov ax,FinishLow            ;put stop times in
  389.     sub ax,StartLow             ;sub start from it - ax now holds difference
  390.  
  391.     mov bx,SEG Output2          ;get segment of Output1 string
  392.     mov ds,bx                   ;put it in ds
  393.     mov bx,OFFSET Output2+12    ;offset is 13 characters into the string
  394.     mov cx,5                    ;convert 5 digits
  395.     call Num2Str
  396.  
  397.     mov bx,SEG Output2          ;get segment of Output1 string
  398.     mov ds,bx                   ;put it in ds
  399.     mov bx,OFFSET Output2       ;get offset of string
  400.     call PrintString            ;print string
  401. ;---------------------------------------------------------------------
  402. ;---------------------------------------------------------------------
  403.  
  404.  
  405.  
  406.  
  407. ;---------------------------------------------------------------------
  408. ;---------------------------------------------------------------------
  409.     ;VARIABLE TO REGISTER
  410.     ;
  411.     ;timing loop
  412.     ;
  413.     xor ax,ax                   ;zero out register
  414.     int 1Ah                     ;how many clock ticks since midnight
  415.     mov StartLow,dx             ;save it (low word)
  416.  
  417.     
  418.     ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  419.     mov Counter,0               ;initialize the loop counter
  420.  
  421. DoIt3:    
  422.     call MemToReg               ;call the variable to register mover proc
  423.     inc Counter                 ;inc the counter
  424.     cmp Counter,40*8            ;40 loops = 1 million
  425.     jne DoIt3                   ;if it's not the required # of loops, do more
  426.     ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  427.  
  428.  
  429.     ;timing loop
  430.     ;
  431.     xor ax,ax                   ;zero out register
  432.     int 1Ah                     ;how many clock ticks since midnight
  433.     mov FinishLow,dx            ;save it (low word)
  434.     
  435.     ;get difference from start and stop times
  436.     xor ax,ax                   ;zero out register
  437.     mov ax,FinishLow            ;put stop times in
  438.     sub ax,StartLow             ;sub start from it - ax now holds difference
  439.  
  440.     mov bx,SEG Output3          ;get segment of Output1 string
  441.     mov ds,bx                   ;put it in ds
  442.     mov bx,OFFSET Output3+12    ;offset is 13 characters into the string
  443.     mov cx,5                    ;convert 5 digits
  444.     call Num2Str
  445.  
  446.     mov bx,SEG Output3          ;get segment of Output1 string
  447.     mov ds,bx                   ;put it in ds
  448.     mov bx,OFFSET Output3       ;get offset of string
  449.     call PrintString            ;print string
  450. ;---------------------------------------------------------------------
  451. ;---------------------------------------------------------------------
  452.  
  453.  
  454.  
  455.  
  456. ;---------------------------------------------------------------------
  457. ;---------------------------------------------------------------------
  458.     ;MEMORY MOVES (requested by Richard)
  459.     ;
  460.     ;timing loop
  461.     ;
  462.     xor ax,ax                   ;zero out register
  463.     int 1Ah                     ;how many clock ticks since midnight
  464.     mov StartLow,dx             ;save it (low word)
  465.  
  466.     
  467.     
  468.     ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  469.     mov Counter,0               ;initialize the loop counter
  470.  
  471. DoIt4:    
  472.     call MemoryMove             ;call the memory mover proc
  473.     inc Counter                 ;inc the counter
  474.     cmp Counter,40*100          ;40 loops = 1 million
  475.     jne DoIt4                   ;if it's not the required # of loops, do more
  476.     ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  477.  
  478.  
  479.     ;timing loop
  480.     ;
  481.     xor ax,ax                   ;zero out register
  482.     int 1Ah                     ;how many clock ticks since midnight
  483.     mov FinishLow,dx            ;save it (low word)
  484.  
  485.  
  486.     ;get difference from start and stop times
  487.     ;
  488.     xor ax,ax                   ;zero out register
  489.     mov ax,FinishLow            ;put stop times in
  490.     sub ax,StartLow             ;sub start from it - ax now holds difference
  491.  
  492.     mov bx,SEG Output4          ;get segment of Output1 string
  493.     mov ds,bx                   ;put it in ds
  494.     mov bx,OFFSET Output4+12    ;offset is 13 characters into the string
  495.     mov cx,5                    ;convert 5 digits
  496.     call Num2Str
  497.  
  498.     mov bx,SEG Output4          ;get segment of Output1 string
  499.     mov ds,bx                   ;put it in ds
  500.     mov bx,OFFSET Output4       ;get offset of string
  501.     call PrintString            ;print string
  502. ;---------------------------------------------------------------------
  503. ;---------------------------------------------------------------------
  504.  
  505.     
  506.  
  507.  
  508.  
  509. ;---------------------------------------------------------------------
  510. ;---------------------------------------------------------------------
  511.     xor ax,ax                   ;zero out register
  512.     call WhichCPU               ;call proc to determine CPU type
  513.     cmp ax,386                  ;is it at least a 386?
  514.     jae Do386Tests              ;yes, go do 386-specific tests
  515.     jmp CreateReport            ;nope, bail out (286 or lower)
  516. ;---------------------------------------------------------------------
  517. ;---------------------------------------------------------------------
  518.  
  519.  
  520.  
  521.  
  522.  
  523. ;---------------------------------------------------------------------
  524. ;---------------------------------------------------------------------
  525. Do386Tests:
  526.     ;EXTENDED REGISTER TO EXTENDED REGISTER
  527.     ;
  528.     ;timing loop
  529.     ;
  530.     
  531.     mov bx,SEG Msg386           ;get segment of Output1 string
  532.     mov ds,bx                   ;put it in ds
  533.     mov bx,OFFSET Msg386        ;get offset of string
  534.     call PrintString            ;print string
  535.     
  536.     
  537.     xor ax,ax                   ;look at the low system timer byte
  538.     int 1Ah                     ;how many clock ticks since midnight
  539.     mov StartLow,dx             ;save it (low word)
  540.  
  541.     
  542.     ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  543.     mov Counter,0               ;initialize the loop counter
  544.  
  545. DoIt5:    
  546.     call ERegToEReg               ;call the extended register mover proc
  547.     inc Counter                 ;inc the counter
  548.     cmp Counter,40*8            ;40 loops = 1 million
  549.     jne DoIt5                   ;if it's not the required # of loops, do more
  550.     ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  551.  
  552.  
  553.     ;timing loop
  554.     ;
  555.     xor ax,ax                   ;look at the low system timer byte
  556.     int 1Ah                     ;how many clock ticks since midnight
  557.     mov FinishLow,dx            ;save it (low word)
  558.  
  559.  
  560.     ;get difference from start and stop times
  561.     xor ax,ax                   ;zero out register
  562.     mov ax,FinishLow            ;put stop times in
  563.     sub ax,StartLow             ;sub start from it - ax now holds difference
  564.  
  565.     mov bx,SEG Output5          ;get segment of Output1 string
  566.     mov ds,bx                   ;put it in ds
  567.     mov bx,OFFSET Output5+12    ;offset is 13 characters into the string
  568.     mov cx,5                    ;convert 5 digits
  569.     call Num2Str
  570.  
  571.     mov bx,SEG Output5          ;get segment of Output1 string
  572.     mov ds,bx                   ;put it in ds
  573.     mov bx,OFFSET Output5       ;get offset of string
  574.     call PrintString            ;print string
  575.  
  576. ;---------------------------------------------------------------------
  577. ;---------------------------------------------------------------------
  578.  
  579.  
  580.  
  581.  
  582.  
  583. ;---------------------------------------------------------------------
  584. ;---------------------------------------------------------------------
  585.     ;VARIABLE TO EXTENDED REGISTER
  586.     ;
  587.     ;timing loop
  588.     ;
  589.     xor ax,ax                   ;look at the low system timer byte
  590.     int 1Ah                     ;how many clock ticks since midnight
  591.     mov StartLow,dx             ;save it (low word)
  592.  
  593.     
  594.     ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  595.     mov Counter,0               ;initialize the loop counter
  596.  
  597. DoIt6:    
  598.     call MemToEReg                ;call the variable to register mover proc
  599.     inc Counter                 ;inc the counter
  600.     cmp Counter,40*8            ;40 loops = 1 million
  601.     jne DoIt6                   ;if it's not the required # of loops, do more
  602.     ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  603.  
  604.  
  605.     ;timing loop
  606.     ;
  607.     xor ax,ax                   ;look at the low system timer byte
  608.     int 1Ah                     ;how many clock ticks since midnight
  609.     mov FinishLow,dx            ;save it (low word)
  610.     
  611.     ;get difference from start and stop times
  612.     xor ax,ax                   ;zero out register
  613.     mov ax,FinishLow            ;put stop times in
  614.     sub ax,StartLow             ;sub start from it - ax now holds difference
  615.  
  616.     mov bx,SEG Output6          ;get segment of Output1 string
  617.     mov ds,bx                   ;put it in ds
  618.     mov bx,OFFSET Output6+12    ;offset is 13 characters into the string
  619.     mov cx,5                    ;convert 5 digits
  620.     call Num2Str
  621.  
  622.     mov bx,SEG Output6          ;get segment of Output1 string
  623.     mov ds,bx                   ;put it in ds
  624.     mov bx,OFFSET Output6       ;get offset of string
  625.     call PrintString            ;print string
  626. ;---------------------------------------------------------------------
  627. ;---------------------------------------------------------------------
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634.  
  635. CreateReport:
  636.     ;display default prompt
  637.     mov ax,SEG CRLF
  638.     mov ds,ax
  639.     mov bx,OFFSET CRLF
  640.     call PrintString
  641.     
  642.     mov ax,SEG Prompt
  643.     mov ds,ax
  644.     mov bx,OFFSET Prompt
  645.     call PrintString
  646.     
  647.     ;get user input         
  648.     xor ax,ax               ;zero out register
  649.     xor bx,bx               ;zero out register
  650.     xor cx,cx               ;zero out register
  651.     xor dx,dx               ;zero out register
  652.     mov ah,3Fh              ;function to ????????
  653.     xor bx,bx               ;zero out register
  654.     mov cx,73               ;# of bytes to get
  655.     mov dx,SEG UserInput    ;get segment of string to hold user's input
  656.     mov ds,dx               ;put it in ds
  657.     mov dx,OFFSET UserInput ;put offset of same string into dx
  658.     int 21h                 ;call DOS to do it
  659.  
  660.     
  661. Open:    
  662.     mov ax,SEG FileName     ;get segment of filename
  663.     mov ds,ax               ;put it in ds
  664.     mov dx,OFFSET FileName  ;get offset of filename
  665.     mov ah,3Dh              ;function to open a file
  666.     mov al,00000010b        ;bit 1 (zero-based) set for read/write access
  667.     int 21h                 ;call DOS to do it
  668.     mov Handle,ax           ;save handle
  669.     jnc SeekEnd
  670.  
  671.     
  672. Create:
  673.     mov ax,SEG FileName     ;get segment of filename
  674.     mov ds,ax               ;put it in ds
  675.     mov dx,OFFSET FileName  ;get offset of filename
  676.     mov ah,3Ch              ;function to create a file
  677.     mov cl,00100000b        ;bit 5 (zero-based) set means file is normal
  678.     int 21h                 ;call DOS to do it
  679.  
  680.     mov ax,SEG FileName     ;get segment of filename
  681.     mov ds,ax               ;put it in ds
  682.     mov dx,OFFSET FileName  ;get offset of filename
  683.     mov ah,3Dh              ;function to open a file
  684.     mov al,00000010b        ;bit 1 (zero-based) set for read/write access
  685.     int 21h                 ;call DOS to do it
  686.     mov Handle,ax           ;save handle
  687.     jnc SeekEnd
  688.  
  689.  
  690. CreateError:
  691.     mov ax,SEG BadCreate    ;point to error msg about creating the file
  692.     mov ds,ax               ;put it in ds
  693.     mov bx,OFFSET BadCreate ;put offset in bx
  694.     call PrintString        ;print the msg
  695.     jmp Done                ;bail out
  696.  
  697.  
  698. SeekEnd:
  699.     mov ah,42h              ;function to set current file position
  700.     mov al,02h              ;02 = end of file
  701.     mov bx,Handle           ;handle from opening file
  702.     mov cx,0                ;high byte of offset from file position
  703.     mov dx,0                ;low byte of offset from file position
  704.     int 21h                 ;call DOS to do it
  705.     
  706.     
  707. Write:                      
  708.     mov ax,SEG Output1      ;get segment of string to write to disk
  709.     mov ds,ax               ;put it in ds
  710.     mov dx,OFFSET Output1   ;get offset of string to write to disk
  711.     xor ax,ax               ;zero out register
  712.     mov ah,40h              ;function to write to device/file (handle)
  713.     mov bx,Handle           ;handle to write to (saved from OPEN function)
  714.     mov cx,73               ;how many characters to write
  715.     int 21h                 ;call DOS to do it
  716.  
  717.     mov ax,SEG Output2      ;get segment of string to write to disk
  718.     mov ds,ax               ;put it in ds
  719.     mov dx,OFFSET Output2   ;get offset of string to write to disk
  720.     xor ax,ax               ;zero out register
  721.     mov ah,40h              ;function to write to device/file (handle)
  722.     mov bx,Handle           ;handle to write to (saved from OPEN function)
  723.     mov cx,73               ;how many characters to write
  724.     int 21h                 ;call DOS to do it
  725.  
  726.     mov ax,SEG Output3      ;get segment of string to write to disk
  727.     mov ds,ax               ;put it in ds
  728.     mov dx,OFFSET Output3   ;get offset of string to write to disk
  729.     xor ax,ax               ;zero out register
  730.     mov ah,40h              ;function to write to device/file (handle)
  731.     mov bx,Handle           ;handle to write to (saved from OPEN function)
  732.     mov cx,73               ;how many characters to write
  733.     int 21h                 ;call DOS to do it
  734.  
  735.     mov ax,SEG Output4      ;get segment of string to write to disk
  736.     mov ds,ax               ;put it in ds
  737.     mov dx,OFFSET Output4   ;get offset of string to write to disk
  738.     xor ax,ax               ;zero out register
  739.     mov ah,40h              ;function to write to device/file (handle)
  740.     mov bx,Handle           ;handle to write to (saved from OPEN function)
  741.     mov cx,73               ;how many characters to write
  742.     int 21h                 ;call DOS to do it
  743.  
  744.     mov ax,SEG Msg386       ;get segment of string to write to disk
  745.     mov ds,ax               ;put it in ds
  746.     mov dx,OFFSET Msg386    ;get offset of string to write to disk
  747.     xor ax,ax               ;zero out register
  748.     mov ah,40h              ;function to write to device/file (handle)
  749.     mov bx,Handle           ;handle to write to (saved from OPEN function)
  750.     mov cx,73               ;how many characters to write
  751.     int 21h                 ;call DOS to do it
  752.  
  753.     mov ax,SEG Output5      ;get segment of string to write to disk
  754.     mov ds,ax               ;put it in ds
  755.     mov dx,OFFSET Output5   ;get offset of string to write to disk
  756.     xor ax,ax               ;zero out register
  757.     mov ah,40h              ;function to write to device/file (handle)
  758.     mov bx,Handle           ;handle to write to (saved from OPEN function)
  759.     mov cx,73               ;how many characters to write
  760.     int 21h                 ;call DOS to do it
  761.  
  762.     mov ax,SEG Output6      ;get segment of string to write to disk
  763.     mov ds,ax               ;put it in ds
  764.     mov dx,OFFSET Output6   ;get offset of string to write to disk
  765.     xor ax,ax               ;zero out register
  766.     mov ah,40h              ;function to write to device/file (handle)
  767.     mov bx,Handle           ;handle to write to (saved from OPEN function)
  768.     mov cx,73               ;how many characters to write
  769.     int 21h                 ;call DOS to do it
  770.     
  771.     mov ax,SEG UserInput    ;get segment of string to write to disk
  772.     mov ds,ax               ;put it in ds
  773.     mov dx,OFFSET UserInput ;get offset of string to write to disk
  774.     xor ax,ax               ;zero out register
  775.     mov ah,40h              ;function to write to device/file (handle)
  776.     mov bx,Handle           ;handle to write to (saved from OPEN function)
  777.     mov cx,73               ;how many characters to write
  778.     int 21h                 ;call DOS to do it
  779.  
  780.     mov ax,SEG Delimit      ;get segment of string to write to disk
  781.     mov ds,ax               ;put it in ds
  782.     mov dx,OFFSET Delimit   ;get offset of string to write to disk
  783.     xor ax,ax               ;zero out register
  784.     mov ah,40h              ;function to write to device/file (handle)
  785.     mov bx,Handle           ;handle to write to (saved from OPEN function)
  786.     mov cx,73               ;how many characters to write
  787.     int 21h                 ;call DOS to do it
  788.  
  789.     
  790. Close:
  791.     mov ah,3Eh              ;function to close
  792.     mov bx,Handle           ;handle to close (saved from OPEN function)
  793.     int 21h                 ;call DOS to do it
  794.  
  795.  
  796. Done:
  797.     mov ax,4C00h            ;function to terminate program & normal exit code
  798.     int 21h                 ;call DOS to do it
  799.     END                     ;gone...
  800.